コンテナベースデプロイ環境のためのdocker-registry use S3を構築する
はじめに
Amazon Linux AMI 2014.03でDockerが公式yumリポジトリに登録された事により、コンテナベースでのデプロイが現実的な選択肢となってきました。
一般的なアプリケーション開発のデプロイ環境としては、開発を行うStaging環境とサービス稼働環境としてのProduction環境に分離することが多いですが、コンテナベースでも同様にStagingとProducitonを分離することになるでしょう。そうした場合、作成したコンテナイメージをローカルに管理する仕組みが必要になります。
そこで今回はこのローカルでDockerのコンテナイメージを管理する仕組み、docker-registryをAWS上に構築してみました。docker-registryによるデプロイイメージは以下の形です。Staging環境で作成したコンテナイメージをdocker-registryにPushし、docker-registoryはそのコンテナイメージをS3に保存します。Production環境は新しいバージョンのシステムが構築されたコンテナイメージをPullで取得し、既存環境とは別のポートで起動します。最終的にテストが完了した後、ELBの振り分け先を新しいコンテナイメージのポートに変更することで、デプロイが完了します。
docker-registryの構築
dockerのインストール
OSはAmazon Linux AMI 2014.03です。docker-registryはdockerのイメージとして配布されていますので、まずはdockerのインストールとサービス起動を行います。
$ sudo yum install docker $ sudo chkconfig docker on $ sudo service docker start Starting cgconfig service: [ OK ] Starting docker: [ OK ]
設定ファイルの作成
docker-registryはyamlファイルで設定を行います。その際複数の設定をFlavorとして定義しておくことができ、環境変数SETTINGS_FLAVORによって切り替えることが出来ます。デフォルトではdevという名前が使われるようになっています。
今回想定している環境では複数のFlavorを作る必要が無いので、デフォルトのdevという名前で定義を作成します。またcommonには共通定義を書くことが出来ます。
S3バケットは事前に作成しておきます。storage_pathで指定したフォルダは自動的に作成されますので事前作成は不要です。
$ sudo vi /home/ec2-user/dr-conf/config.yml common: loglevel: info secret_key: _env:REGISTRY_SECRET standalone: true disable_token_auth: true dev: storage: s3 s3_access_key: _env:AWS_S3_ACCESS_KEY s3_secret_key: _env:AWS_S3_SECRET_KEY s3_region: ap-northeast-1 s3_bucket: docker-reg boto_bucket: docker-reg s3_encrypt: true s3_secure: true storage_path: /images
docker-registoryの起動
それではdocker-registryを起動します。registryというイメージを指定して、上記で作成したconfig.ymlを配置したディレクトリをVOLUMEオプションでマウントし、環境変数を定義した状態でdocker runします。 環境変数としてはConfigファイルを指定するDOCKER_REGISTRY_CONFIGと、Configファイルの中で定義している3つの環境変数(REGISTRY_SECRET、AWS_S3_ACCESS_KEY、AWS_S3_SECRET_KEY)を渡します。 AWS_S3_ACCESS_KEYとAWS_S3_SECRET_KEYはS3にアクセスするための適切なKEYを設定して下さい。REGISTRY_SECRETはbase64エンコードされたパスフレーズを設定します。
$ sudo docker run -p 5000:5000 -v /home/ec2-user/dr-conf:/dr-conf -e DOCKER_REGISTRY_CONFIG=/dr-conf/config.yml -e AWS_S3_ACCESS_KEY="<アクセスキー>" -e AWS_S3_SECRET_KEY="<シークレットキー>" -e REGISTRY_SECRET="<base64エンコードしたパスフレーズ>" registry 2014-05-11 02:35:59,543 INFO: Boto based storage initialized 2014-05-11 02:35:59 [1] [INFO] Starting gunicorn 18.0 2014-05-11 02:35:59 [1] [INFO] Listening at: http://0.0.0.0:5000 (1) 2014-05-11 02:35:59 [1] [INFO] Using worker: gevent
これでdocker-registryが起動しました。
デプロイしてみる
Staging環境からのPush
172.31.3.232というIPアドレスがdocker-registoryを構築したサーバのIPアドレスです。Staging環境で作成したコンテナイメージにtagを設定します。ここではtagを日付+リビジョン番号としていますが、開発定義に合わせてtagを設定して下さい。
$ sudo docker tag d70588f3888c 172.31.3.232:5000/app:20140511r01 $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE app 20140511r01 d70588f3888c 54 minutes ago 351.9 MB 172.31.3.232:5000/app 20140511r01 d70588f3888c 54 minutes ago 351.9 MB
ではpushしてみます。
$ sudo docker push 172.31.3.232:5000/app The push refers to a repository [172.31.3.232:5000/app] (len: 1) Sending image list Pushing repository 172.31.3.232:5000/app (1 tags) 511136ea3c5a: Image successfully pushed 7064731afe90: Image successfully pushed 0b443ba03958: Image successfully pushed d70588f3888c: Image successfully pushed Pushing tag for rev [d70588f3888c] on {http://172.31.3.232:5000/v1/repositories/app/tags/20140511r01}
push出来ました!S3バケットを確認すると、以下のようにイメージが保存されていることが分かります。
Production環境でのPull
次にProduction環境でPullし、Staging環境で作成したイメージを取得します。
$ sudo docker pull 172.31.3.232:5000/app:20140511r01 Pulling repository 172.31.3.232:5000/app d70588f3888c: Download complete 511136ea3c5a: Download complete 7064731afe90: Download complete 0b443ba03958: Download complete $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 172.31.3.232:5000/app 20140511r01 d70588f3888c 57 minutes ago 351.9 MB
あとはこのイメージをProduction環境で起動し、ELBで振り分け先ポートを新しいイメージのポート番号にしてあげれば、デプロイ環境です!
まとめ
Dockerはこういった周辺ツールが最近かなり整備されてきたように思います。既に商用環境でコンテナデプロイをしているという事例も、少ないながらも耳にする様になってきました。Dockerの今後の動向は要チェックですね。まずはDocker 1.0が楽しみです!